package com.dreamchaser;

import com.dreamchaser.domain.Book;
import com.dreamchaser.util.DateUtil;
import com.dreamchaser.util.Displayer;
import com.dreamchaser.util.FileUtil;

import java.math.BigDecimal;
import java.util.*;

public class PatternNoSql {
    static Scanner scanner = new Scanner(System.in);
    /**
     * 维护的链表
     */
    static List<Book> list = new LinkedList<>();
    static Book book = new Book();



    /**
     * 二级模块
     *
     * @param i 用于递归时判断其是否是第一次来还是输入错误来的
     * @return 用于返回上一级, 返回1就表示需要返回上一级，返回0则说明继续执行
     */
    public static int chooseFunction(int i) {
        if (i == 1) {
            System.out.println("\n\n功能：");
            System.out.println("1.图书信息录入");
            System.out.println("2.图书信息浏览");
            System.out.println("3.插入图书信息");
            System.out.println("4.查询");
            System.out.println("5.排序");
            System.out.println("6.修改图书信息");
            System.out.println("7.删除图书信息");
            System.out.println("8.导出为文件");
            System.out.println("9.返回模式选择");
            System.out.println("\n\n请输入你需要选择的功能（序号）：");
        }

        while (true) {
            switch (scanner.nextInt()) {
                case 1:
                    saveFile();
                    return 0;
                case 2:
                    selectAll();
                    return 0;
                case 3:
                    addOneBook();
                    return 0;
                case 4:
                    while (true) {
                        if (chooseSelect(1) == 1) {
                            return 0;
                        }
                    }
                case 5:
                    while (true) {
                        if (chooseOrder(1) == 1) {
                            return 0;
                        }
                    }
                case 6:
                    updateBook();
                    return 0;
                case 7:
                    deleteOne();
                    return 0;
                case 8:
                    writeToFile();
                    return 0;
                case 9:
                    return 1;
                default:
                    System.out.println("抱歉，输入的是非法字符，请重新输入：");
                    return chooseFunction(0);
            }
        }
    }

    private static void writeToFile() {
        System.out.println("请输入你要保存的文件名（如：dreamchaser.txt）：");
        scanner.nextLine();
        Boolean flag=FileUtil.writeFile(list,scanner.nextLine());
        if (flag){
            System.out.println("保存成功！");
        }else {
            System.out.println("保存失败，请确认输入的文件路径是否正确！");
        }
    }

    private static void deleteOne() {
        System.out.println("请输入你要删除书籍的图书编号：");
        int id = scanner.nextInt();
        boolean flag = list.removeIf(a -> a.getId() == id);
        if (flag) {
            System.out.println("删除成功！");
        } else {
            System.out.println("未找到相应的图书！");
        }
    }

    private static void updateBook() {
        book.clear();
        System.out.println("请输入你要更新的书籍图书编号：");
        book.setId(scanner.nextInt());
        scanner.nextLine();
        System.out.println("是否要修改其图书名称（若是，请输入其名称，若否，则输入“否”）：");
        String title = scanner.nextLine();
        if (!title.equals("否")) {
            book.setTitle(title);
        }
        System.out.println("是否要修改其作者姓名（若是，请输入其姓名，若否，则输入“否”）：");
        String name = scanner.nextLine();
        if (!name.equals("否")) {
            book.setName(name);
        }
        System.out.println("是否要修改其出版社（若是，请输入其出版社名称，若否，则输入“否”）：");
        String publisher = scanner.nextLine();
        if (!publisher.equals("否")) {
            book.setPublisher(publisher);
        }
        System.out.println("是否要修改其出版时间（若是，请输入其时间，请以“2020/10/06”的形式输入时间，若否，则输入“否”）：");
        String time = scanner.nextLine();
        if (!time.equals("否")) {
            book.setTime(new Date(time));
        }
        System.out.println("是否要修改其价格（若是，请输入其价格，若否，则输入“否”）：");
        String price = scanner.nextLine();
        if (!price.equals("否")) {
            book.setPrice(new BigDecimal(price));
        }
        for (Book book1 : list) {
            if (book1.getId().equals(book.getId())) {
                list.remove(book1);
                list.add(book);
            }
        }
        System.out.println("更新成功！");
    }

    private static void saveFile() {
        System.out.println("请输入要录入的文件（txt，且需每一行都是一条记录）路径（绝对路径或者相对路径皆可）：");
        //把回车吃掉
        scanner.nextLine();
        List<String> list1 = FileUtil.readTxtFile(scanner.nextLine());
        String[] strings = null;
        if (list1 != null) {
            for (String s : list1) {
                strings = s.split(" |\n");
                book.clear();
                book.setId(Integer.parseInt(strings[0]));
                book.setTitle(strings[1]);
                book.setName(strings[2]);
                book.setPublisher(strings[3]);
                book.setTime(DateUtil.stringToDate(strings[4], "yyyy/MM/dd"));
                book.setPrice(new BigDecimal(strings[5]));
                list.add(book);
            }
            System.out.println("录入成功");
        } else {
            System.out.println("文件未找到或者文件不符合要求。请重新输入！");
        }

    }

    private static void selectAll() {
        Displayer.show(list);
    }

    private static void addOneBook() {
        book.clear();
        System.out.println("请输入你要插入书籍的图书编号：");
        book.setId(scanner.nextInt());
        scanner.nextLine();
        System.out.println("请输入你要插入书籍的图书名称：");
        String title = scanner.nextLine();
        book.setTitle(title);
        System.out.println("请输入你要插入书籍的作者姓名：");
        String name = scanner.nextLine();
        book.setName(name);
        System.out.println("请输入你要插入书籍的出版社（若是，请输入其出版社名称，若否，则输入“否”）：");
        String publisher = scanner.nextLine();
        if (!publisher.equals("否")) {
            book.setPublisher(publisher);
        }
        System.out.println("请输入你要插入书籍的出版时间（若是，请输入其时间，请以“2020/10/06”的形式输入时间，若否，则输入“否”）：");
        String time = scanner.nextLine();
        if (!time.equals("否")) {
            book.setTime(new Date(time));
        }
        System.out.println("请输入你要插入书籍的价格（若是，请输入其价格，若否，则输入“否”）：");
        String price = scanner.nextLine();
        if (!price.equals("否")) {
            book.setPrice(new BigDecimal(price));
        }
        list.add(book);
        System.out.println("插入成功");
    }

    /**
     * 排序模块
     * 三级模块
     *
     * @param i
     * @return
     */
    private static int chooseOrder(int i) {
        if (i == 1) {
            System.out.println("\n\n排序：");
            System.out.println("1.按图书编号排序");
            System.out.println("2.按书名排序");
            System.out.println("3.按出版时间排序");
            System.out.println("4.按价格排序等");
            System.out.println("5.返回功能选择");
            System.out.println("\n\n请输入你需要的排序方式（序号）：");
        }

        while (true) {
            switch (scanner.nextInt()) {
                case 1:
                    selectOrderById();
                    return 0;
                case 2:
                    selectOrderByTitle();
                    return 0;
                case 3:
                    selectOrderByTime();
                    return 0;
                case 4:
                    selectOrderByPrice();
                    return 0;
                case 5:
                    return 1;
                default:
                    System.out.println("抱歉，输入的是非法字符，请重新输入：");
                    return chooseFunction(0);
            }
        }
    }

    private static void selectOrderByPrice() {
        /**
         * 把 x -> System.out.println(x) 简化为 System.out::println 的过程称之为 eta-conversion
         * 把 System.out::println 简化为 x -> System.out.println(x) 的过程称之为 eta-expansion
         * 范式:
         * 类名::方法名
         * 方法调用
         *
         * person -> person.getAge();
         * 可以替换成
         * Person::getAge
         *
         * x -> System.out.println(x)
         * 可以替换成
         * System.out::println
         * out是一个PrintStream类的对象，println是该类的方法，依据x的类型来重载方法
         * 创建对象
         *
         * () -> new ArrayList<>();
         * 可以替换为
         * ArrayList::new
         */
        list.sort(Comparator.comparing(Book::getPrice));
        Displayer.show(list);
    }

    private static void selectOrderByTime() {
        list.sort(Comparator.comparing(Book::getTime));
        Displayer.show(list);
    }

    private static void selectOrderByTitle() {
        list.sort(Comparator.comparing(Book::getTitle));
        Displayer.show(list);
    }

    private static void selectOrderById() {
        list.sort(Comparator.comparing(Book::getId));
        Displayer.show(list);
    }

    /**
     * 查询模块
     * 三级模块
     *
     * @param i
     * @return
     */
    private static int chooseSelect(int i) {
        if (i == 1) {
            System.out.println("\n\n查询：");
            System.out.println("1.按书名查询");
            System.out.println("2.按作者名查询");
            System.out.println("3.按价格查询(小于)");
            System.out.println("4.按价格查询（等于）");
            System.out.println("5.按价格查询（大于）");
            System.out.println("6.返回模式选择");
            System.out.println("\n\n请输入你需要的查询方式（序号）：");
        }

        while (true) {
            switch (scanner.nextInt()) {
                case 1:
                    selectByTitle();
                    return 0;
                case 2:
                    selectByName();
                    return 0;
                case 3:
                    selectByPriceS();
                    return 0;
                case 4:
                    selectByPrice();
                    return 0;
                case 5:
                    selectByPriceB();
                    return 0;
                case 6:
                    return 1;
                default:
                    System.out.println("抱歉，输入的是非法字符，请重新输入：");
                    return chooseFunction(0);
            }
        }
    }

    private static void selectByPriceB() {
        System.out.println("请输入你要查询的价格：");
        List<Book> result = new LinkedList<>();
        for (Book book1 : list) {
            if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == 1) {
                result.add(book1);
            }
        }
        Displayer.show(result);
    }

    private static void selectByPrice() {
        System.out.println("请输入你要查询的价格：");
        List<Book> result = new LinkedList<>();
        for (Book book1 : list) {
            if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == 0) {
                result.add(book1);
            }
        }
        Displayer.show(result);
    }

    private static void selectByPriceS() {
        System.out.println("请输入你要查询的价格：");
        List<Book> result = new LinkedList<>();
        for (Book book1 : list) {
            if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == -1) {
                result.add(book1);
            }
        }
        Displayer.show(result);
    }

    private static void selectByName() {
        System.out.println("请输入你要查询的作者姓名：");
        //因为后面是nextLine,而之前是nextInt，会算上回车键，所以得先用nextLine吃掉回车
        scanner.nextLine();
        List<Book> result = new LinkedList<>();
        for (Book book1 : list) {
            if (book1.getName().equals(scanner.nextLine())) {
                result.add(book1);
            }
        }
        Displayer.show(result);
    }

    private static void selectByTitle() {
        System.out.println("请输入你要查询的书籍名称：");
        scanner.nextLine();
        List<Book> result = new LinkedList<>();
        for (Book book1 : list) {
            if (book1.getTitle().equals(scanner.nextLine())) {
                result.add(book1);
            }
        }
        Displayer.show(result);
    }
}
